package com.ktgj.flight.common.huaxia;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ktgj.common.core.enums.ChinaExpressEnum;
import com.ktgj.common.core.enums.EnumHelper;
import com.ktgj.common.core.utils.StringUtils;
import com.ktgj.flight.common.BaseClass;
import com.ktgj.flight.common.ruili.drdomain.BookingContactInfo;
import com.ktgj.flight.common.huaxia.domain.*;
import com.ktgj.common.core.keyutil.AesUtil;
import com.ktgj.common.core.keyutil.RSAUtil;
import com.ktgj.common.core.keyutil.ZipUtils;
import com.ktgj.common.core.keyutil.helper.EncryptHelper;
import com.ktgj.common.core.keyutil.model.EncryptMessageModel;
import com.ktgj.flight.domain.Airport;
import com.ktgj.flight.domain.InterfaceEntity.*;
import com.ktgj.flight.service.IAirportService;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.security.interfaces.RSAPublicKey;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 华夏航空对接（二字码G5）
 */
@Service
public class _G5 extends BaseClass {

    @Autowired
    private IAirportService airportService;

    static RestTemplate restTemplate = new RestTemplate();

    private List<String> ListAllowIp;

    public _G5() {
        ListAllowIp = new ArrayList<>();
        ListAllowIp.add("172.16.2.65:99");
    }

    public static Object Obj = new Object();

    //当前请求数量
    public static int RequestCount = 0;

    //最大支持20
    public int RequestMaxNum = 20;

    //身份编号
    private final String userName = "jsj";

    //测试环境
    //密码
    /*private final String password = "ec5d84b5cc3511e89492022fcf7b6d4a";
    //RSA密钥
    private final String rsaKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQUc/9pXTsowj4D/Vl83FPgDnY92JjEJuOH39rYwp/98JLdQu53S4OhUdiOIYrFQcnf/p21crhOZXAX4nb/I+5GYXWl3QyD9pZ6XResxsAQ7C/cpurg+zM4jNjkdQH5ldbMVyqCTnXAgbR0z+Q0G+Q8rPNVUT3JDgG0LsVs0XCfQIDAQAB";
    //AES密钥
    private final String aesKey = "zBpxOiAHCAv2SuJxPoqTSg==";
    //接口域名
    private final String url = "http://222.178.225.36:8126/";
    private final String aesPassWord="chinaexpressair.com";*/


    //线上环境
    //密码
    private final String password = "76c7a720e23a11e89492022fcf7b6d4a";
    //RSA密钥
    private final String rsaKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXy6+VvD5Ux4dTGPXlrFYVjphcHiAZyX2e9qpZPqHio92BNgKsTTqwKD7A4/V8Rm0jT1tqe8sC/UD0DQ5nmadbzAnwBJ8wL5XGXQnmOKOpUFnyIYutS55kjn6HedP6yWW4H5PPbjh33gQPZvVIAR2Beh7orissSqnOC16+4yZnHQIDAQAB";
    //AES密钥
    private final String aesKey = "lIQZdRQl1k4jhhZ03stVRg==";
    //接口域名
    private final String url = "http://stone.chinaexpressair.com:9200/";
    private final String aesPassWord = "chinaexpress.airline";


    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    /**
     * 航班查询
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoFlightSearchResponse _FlightSearch(MoFlightSearchRequest moRequest) {
        moRequest.OnlyCode = (moRequest.OnlyCode != null) ? moRequest.OnlyCode : strOnlyCode();
        MoFlightSearchResponse response = new MoFlightSearchResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        String requestPath = "stone/http/flight/queryFlights";
        Date requestTime = new Date();
        Date returnTime = new Date();
        boolean isRoute = false;
        QueryParms parms = new QueryParms();
        parms.orgCity = moRequest.GoSearchWhere.OrgAirport;
        parms.dstCity = moRequest.GoSearchWhere.DstAirport;
        parms.departDate = moRequest.GoSearchWhere.DepDate;
        parms.routeType = 0;
        parms.ticketType = 0;
        parms.pubChannel = "jsj";
        strRequestData = JSON.toJSONString(parms);
        strResponseData = new _G5().send(requestPath, strRequestData);
        if (StringUtils.isWhitespace(strResponseData)) {
            response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
            response.ErrorMsg = "航班查询,未返回数据";
            response.IsSuccess = false;
            return response;
        }
        //判断是否为基类错误
        FlightRsDto ceResponse = JSON.parseObject(strResponseData, FlightRsDto.class);
        if (!"1".equals(ceResponse.result)) {
            response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
            response.ErrorMsg = ceResponse.msg;
            response.IsSuccess = false;
            return response;
        }
        try {
            //解析华夏返回的航空数据
            for (ItemList nf : ceResponse.itemList) {
                for (SegmentList rs : nf.segmentList) {
                    if (rs.flightType == 1) {
                        //因没有代理服务费暂时屏蔽
                        if ("0".equals(rs.flightType)) {
                            continue;
                        }
                        MoFlightInfo flightInfo = new MoFlightInfo();
                        flightInfo.Airline = rs.airline;
                        flightInfo.FlightNo = rs.fltNumber;
                        flightInfo.PlaneStyle = rs.fltType;
                        flightInfo.voyageNotice = rs.voyageNotice;
                        flightInfo.OrgAirport = rs.depCity;
                        flightInfo.DstAirport = rs.arrCity;
                        flightInfo.DepTerm = rs.depTerm;
                        flightInfo.ArrTerm = rs.arrTerm;
                        flightInfo.DepDate = simpleDateFormat.parse(rs.fltDate + " " + rs.depTime);
                        flightInfo.ArrDate = simpleDateFormat.parse(rs.arrDate + " " + rs.arrTime);
                        flightInfo.IsCodeShare = rs.codeShare;
                        flightInfo.Carrier = rs.realFltNo;
                        flightInfo.StopCount = Integer.parseInt(rs.stopOver);
                        flightInfo.ProductIndex = String.valueOf(nf.index);
                        if (Integer.parseInt(rs.stopOver) > 0) {
                            flightInfo.stopPlace = rs.stopsList.get(0).cityCode;
                            int stop = Integer.parseInt(rs.stopsList.get(0).stopTime);
                            int stopTime = (int) Math.floor(stop / 60);
                            int stopTimes = stop % 60;
                            flightInfo.stopTime = stopTime + "小时" + stopTimes + "分钟";

                            if (rs.segmentList.size() > 0) {
                                flightInfo.stopDate = rs.segmentList.get(0).fltDate + " " + rs.segmentList.get(0).arrTime;
                                if (rs.segmentList.size() > 1) {
                                    flightInfo.stopEndDate = rs.segmentList.get(1).fltDate + " " + rs.segmentList.get(1).depTime;
                                } else {
                                    Date parse = simpleDateFormat.parse(flightInfo.stopDate);
                                    Date date = new Date(parse.getTime() + (stop * 60000));
                                    flightInfo.stopEndDate = simpleDateFormat.format(date);
                                }
                            }
                        }
                        flightInfo.PlaneStyle = rs.fltType;
                        flightInfo.OrgAirportName = getAirPortNameByRirPortCode(rs.depCity);
                        flightInfo.DstAirportName = getAirPortNameByRirPortCode(rs.arrCity);
                        int time = Integer.parseInt(rs.flyTime);
                        int flyTime = (int) Math.floor(time / 60);
                        int flyTimes = time % 60;
                        flightInfo.flightTimes = flyTime + "小时" + flyTimes + "分钟";
                        if (rs.isOvernight.equals("1")) {
                            flightInfo.arrad = Integer.parseInt(rs.isOvernight);
                        }
                        //用第一程到达时间和第二程起飞时间解析经停开始时间及结束时间
                        Date ArriveTime = Convert(new Date());
                        Date DepartTime = Convert(new Date());
                        Date EndTime = Convert(new Date());
                        String flightNo2 = "";
                        String arrTerm1 = "";
                        String depTerm2 = "";
                        if (rs.segmentList != null && rs.segmentList.stream().count() > 0) {
                            for (int i = 0; i < rs.segmentList.stream().count(); i++) {
                                SegmentList segment = rs.segmentList.get(i);
                                if (i == 0) {
                                    if (rs.fltNumber != segment.fltNumber) {
                                        flightInfo.IsCodeShare = true;
                                        flightInfo.Carrier = segment.fltNumber;
                                    }
                                    //第一程到达时间
                                    ArriveTime = simpleDateFormat.parse(segment.arrDate + " " + segment.arrTime);
                                    if (segment.arrTerm != null && !segment.arrTerm.equals(""))
                                        arrTerm1 = segment.arrTerm.replace("--", "");
                                }
                                if (i == rs.segmentList.stream().count() - 1) {
                                    flightNo2 = segment.fltNumber;
                                    //最后一程起飞时间
                                    DepartTime = simpleDateFormat.parse(segment.fltDate + " " + segment.depTime);
                                    EndTime = simpleDateFormat.parse(segment.arrDate + " " + segment.arrTime);
                                    if (segment.depTerm != null && !segment.depTerm.equals(""))
                                        depTerm2 = segment.depTerm.replace("--", "");
                                }
                            }
                        }
                        //解析经停信息
                        if (rs.stopsList != null && rs.stopsList.stream().count() > 0) {
                            for (StopsDto nfs : rs.stopsList) {
                                FlightStopEntity fst = new FlightStopEntity();
                                //天-小时-分钟 提取转分钟
                                //总经停分钟数
                                int minute = 0;
                                if (nfs.stopTime != null) {
                                    String stopTime = RegExUtils.replaceAll(nfs.stopTime, "[^0-9]+", "-").trim();
                                    String[] strArray = stopTime.split("-");
                                    for (int i = 0; i < strArray.length; i++) {
                                        if (i == 0 && !StringUtils.isNotEmpty(strArray[i])) {
                                            minute += Integer.parseInt(strArray[i]) * 24 * 60;
                                        } else if (i == 1 && !StringUtils.isNotEmpty(strArray[i])) {
                                            minute += Integer.parseInt(strArray[i]) * 60;
                                        } else if (!StringUtils.isNotEmpty(strArray[i])) {
                                            minute += Integer.parseInt(strArray[i]);
                                        }
                                    }
                                }
                                fst.Duration = minute;
                                fst.ArriveTime = ArriveTime;
                                fst.DepartTime = DepartTime;
                                fst.StopCityCode = nfs.cityCode;
                                fst.arriveTerm1 = arrTerm1;
                                fst.depTerm2 = depTerm2;
                                fst.flightNo2 = flightNo2;
                                flightInfo.ListFlightStop.add(fst);
                            }
                        }
                        //解析经济舱，公务舱，头等舱的全价（0-直飞，1-通程返回数据规则不同，分开解析）
                        if (rs.flightType == 1) {
                            for (SeatList2 pf : rs.seatList) {
                                MoCabinInfo cabinInfo = new MoCabinInfo();
                                //String strCabinClass = pf.seatClass;
                                //BigDecimal FullAmount = pf.classPrice;
                                //成人
                                if ("0".equals(pf.passengerType)) {
                                    //0-直飞，1-通程
                                    cabinInfo.ProductPolicy.StrProductType = Integer.toString(rs.flightType);
                                    cabinInfo.CallCenterAmountInfo.OrgTicketAmount = pf.classPrice;
                                    //成人票减佣金后的价格
                                    cabinInfo.CallCenterAmountInfo.TicketAmount = pf.agencyFee == null ? pf.classPrice : pf.classPrice.subtract(pf.agencyFee);
                                    cabinInfo.Cabin = pf.seatClass;
                                    if (pf.serviceTagList.size() > 0) {
                                        Optional<ServiceTagList> first = pf.serviceTagList.stream().filter(x -> x.priority == 4).findFirst();
                                        first.ifPresent(serviceTagList -> cabinInfo.CabinRule.Baggage = serviceTagList.title);
                                    }
                                    if (rs.mealCode.equals("")) {
                                        cabinInfo.Meal = "无餐食";
                                    }
                                    if (pf.seatData.equals("A")) {
                                        cabinInfo.CabinLeftDesc = "座位充足";
                                    } else {
                                        cabinInfo.CabinLeftDesc = pf.seatData;
                                    }
                                    if (pf.classType == 0) {
                                        cabinInfo.BaseCabin = "F";
                                        cabinInfo.BaseCabinName = "头等舱";
                                    } else if (pf.classType == 1) {
                                        cabinInfo.BaseCabin = "C";
                                        cabinInfo.BaseCabinName = "公务舱";
                                    } else if (pf.classType == 2) {
                                        cabinInfo.BaseCabin = "Y";
                                        cabinInfo.BaseCabinName = "经济舱";
                                    }
                                    //基建燃油费
                                    flightInfo.FuelTax = rs.fuelsurTax;
                                    flightInfo.AirportTax = rs.airportTax;
                                    if (moRequest.hasChildren) {
                                        Set<String> chdRefund = new HashSet<>();
                                        Set<String> chdChange = new HashSet<>();
                                        Set<String> iftRefund = new HashSet<>();
                                        Set<String> iftChange = new HashSet<>();
                                        rs.seatList.forEach(c -> {
                                            //解析儿童价格
                                            if ("1".equals(c.passengerType) && pf.seatClass.equals(c.seatClass)) {
                                                cabinInfo.CallCenterAmountInfo.OrgChdTicketAmount = c.classPrice;
                                                //儿童票减佣金后的价格
                                                cabinInfo.CallCenterAmountInfo.ChdTicketAmount = c.agencyFee == null ? c.classPrice : c.classPrice.subtract(c.agencyFee);
                                                //儿童基建燃油费
                                                flightInfo.ChildFuelTax = rs.childFuelsurTax;
                                                if (c.refundRules.size() > 0) {
                                                    //退票规定
                                                    for (RefundRule rf : c.refundRules) {
                                                        Map<String, Object> map = new HashMap<>();
                                                        map.put("time", rf.timeQuantum);
                                                        BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.refundRate);
                                                        map.put("refundRules", multiply);
                                                        if (chdRefund.add(rf.timeQuantum + multiply))
                                                            cabinInfo.ChdCabinRule.refundChangeRules.add(map);
                                                    }
                                                }
                                                if (c.rescheRules.size() > 0) {
                                                    //改期规定
                                                    for (RescheRule rf : c.rescheRules) {
                                                        Map<String, Object> map = new HashMap<>();
                                                        map.put("time", rf.timeQuantum);
                                                        BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.rescheRate);
                                                        map.put("changeRules", multiply);
                                                        if (chdChange.add(rf.timeQuantum + multiply))
                                                            cabinInfo.ChdCabinRule.changeRules.add(map);
                                                    }
                                                }
                                                if (c.serviceTagList.size() > 0) {
                                                    Optional<ServiceTagList> first = c.serviceTagList.stream().filter(x -> x.priority == 4).findFirst();
                                                    first.ifPresent(serviceTagList -> cabinInfo.ChdCabinRule.Baggage = serviceTagList.title);
                                                }
                                            }
                                            //解析婴儿价格
                                            else if ("2".equals(c.passengerType) && pf.seatClass.equals(c.seatClass)) {
                                                cabinInfo.CallCenterAmountInfo.OrgIftTicketAmount = c.classPrice;
                                                if (c.refundRules.size() > 0) {
                                                    //退票规定
                                                    for (RefundRule rf : c.refundRules) {
                                                        Map<String, Object> map = new HashMap<>();
                                                        map.put("time", rf.timeQuantum);
                                                        BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.refundRate);
                                                        map.put("refundRules", multiply);
                                                        if (iftRefund.add(rf.timeQuantum + multiply))
                                                            cabinInfo.IftCabinRule.refundChangeRules.add(map);
                                                    }
                                                }
                                                if (c.rescheRules.size() > 0) {
                                                    //改期规定
                                                    for (RescheRule rf : c.rescheRules) {
                                                        Map<String, Object> map = new HashMap<>();
                                                        map.put("time", rf.timeQuantum);
                                                        BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.rescheRate);
                                                        map.put("changeRules", multiply);
                                                        if (iftChange.add(rf.timeQuantum + multiply))
                                                            cabinInfo.IftCabinRule.changeRules.add(map);
                                                    }
                                                }
                                                if (c.serviceTagList.size() > 0) {
                                                    Optional<ServiceTagList> first = c.serviceTagList.stream().filter(x -> x.priority == 4).findFirst();
                                                    cabinInfo.IftCabinRule.Baggage = first.get().title;
                                                }
                                            }
                                        });
                                    }
                                    //解析舱位和剩余座位
                                    /*String seatData = pf.seatData;
                                    int seatCount = 0;
                                    String strM = "^[0-9]+$";
                                    Pattern p = Pattern.compile(strM);
                                    Matcher matcher = p.matcher(seatData);
                                    if (matcher.equals(seatData)) {
                                        seatCount = Integer.parseInt(seatData);
                                    } else {
                                        //A代表座位充足，其它为不可销售仓位
                                        if ("A".equals(seatData)) {
                                            seatCount = 10;
                                        } else {
                                            seatCount = 0;
                                        }
                                    }
                                    cabinInfo.CabinLeft = seatCount;*/
                                    if (pf.refundRules.stream().count() > 0) {
                                        //退票规定
                                        for (RefundRule rf : pf.refundRules) {
                                            Map<String, Object> map = new HashMap<>();
                                            map.put("time", rf.timeQuantum);
                                            BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.refundRate);
                                            map.put("refundRules", multiply);
                                            cabinInfo.CabinRule.refundChangeRules.add(map);
                                        }
                                    }
                                    if (pf.rescheRules.stream().count() > 0) {
                                        //改期规定
                                        for (RescheRule rf : pf.rescheRules) {
                                            Map<String, Object> map = new HashMap<>();
                                            map.put("time", rf.timeQuantum);
                                            BigDecimal multiply = cabinInfo.CallCenterAmountInfo.OrgTicketAmount.multiply(rf.rescheRate);
                                            map.put("changeRules", multiply);
                                            cabinInfo.CabinRule.changeRules.add(map);
                                        }
                                    }
                                    //有价格才添加航班信息
                                    if (pf.classPrice.intValue() > 0) {
                                        flightInfo.ListCabinInfo.add(cabinInfo);
                                    }
                                }
                            }
                        }

                        //无直飞航班，屏蔽掉
                        /* else {
                            //通程解析舱位价格
                            List<SeatList2> seatList = rs.seatList;
                            for (int i = 0; i < seatList.stream().count(); i++) {
                                MoCabinInfo cabinInfo = new MoCabinInfo();
                                //String strCabinClass = seatList.get(i).seatClass;
                                //BigDecimal FullAmount = seatList.get(i).classPrice;
                                //成人
                                if ("0".equals(seatList.get(i).passengerType)) {
                                    //0-直飞，1-通程
                                    cabinInfo.ProductPolicy.StrProductType = Integer.toString(rs.flightType);
                                    cabinInfo.CallCenterAmountInfo.OrgTicketAmount = seatList.get(i).classPrice;
                                    //成人票价减佣金后的价格
                                    cabinInfo.CallCenterAmountInfo.TicketAmount = seatList.get(i).agencyFee.intValue() <= 0 ? seatList.get(i).classPrice : seatList.get(i).classPrice.subtract(seatList.get(i).agencyFee);
                                    cabinInfo.Cabin = seatList.get(i).seatClass;
                                    //基建燃油费
                                    flightInfo.FuelTax = rs.fuelsurTax;
                                    flightInfo.AirportTax = rs.airportTax;
                                    //儿童基建燃油费
                                    flightInfo.ChildFuelTax = rs.childFuelsurTax;
                                    //解析舱位和剩余座位
                                    *//*String seatData = seatList.get(i).seatData;
                                    int seatCount = 0;
                                    String strM = "^[0-9]+$";
                                    Pattern p = Pattern.compile(strM);
                                    Matcher matcher = p.matcher(seatData);
                                    if (matcher.equals(seatData)) {
                                        seatCount = Integer.parseInt(seatData);
                                    } else {
                                        //A代表座位充足，其它为不可销售仓位
                                        if ("A".equals(seatData)) {
                                            seatCount = 10;
                                        } else {
                                            seatCount = 0;
                                        }
                                    }
                                    cabinInfo.CabinLeft = seatCount;*//*
                                    if ("A".equals(seatList.get(i).seatData))
                                        cabinInfo.CabinLeftDesc = "座位充足";
                                    else
                                        cabinInfo.CabinLeftDesc = seatList.get(i).seatData;

                                    if (rs.mealCode.equals("")) {
                                        cabinInfo.Meal = "无餐食";
                                    }
                                    if (seatList.get(i).seatData.equals("A")) {
                                        cabinInfo.CabinLeftDesc = "座位充足";
                                    } else {
                                        cabinInfo.CabinLeftDesc = seatList.get(i).seatData;
                                    }
                                    if (seatList.get(i).classType == 0) {
                                        cabinInfo.BaseCabin = "F";
                                        cabinInfo.BaseCabinName = "头等舱";
                                    } else if (seatList.get(i).classType == 1) {
                                        cabinInfo.BaseCabin = "C";
                                        cabinInfo.BaseCabinName = "公务舱";
                                    } else if (seatList.get(i).classType == 2) {
                                        cabinInfo.BaseCabin = "Y";
                                        cabinInfo.BaseCabinName = "经济舱";
                                    }

                                    if (seatList.get(i).refundRules.stream().count() > 0) {
                                        String refund = "";
                                        //退票规定
                                        for (RefundRule rf : seatList.get(i).refundRules) {
                                            refund += String.format(rf.timeQuantum + ",退票手续费为" + Math.round(seatList.get(i).classPrice.multiply(rf.refundRate).intValue()) + "元;");
                                        }
                                        cabinInfo.CabinRule.Refund = refund.trim();
                                    }
                                    if (seatList.get(i).rescheRules.stream().count() > 0) {
                                        String rescheRules = "";
                                        //改期规定
                                        for (RescheRule rf : seatList.get(i).rescheRules) {
                                            rescheRules += rf.timeQuantum + (rf.rescheRate.intValue() == 1 ? "" : ",改期手续费为" + Math.round(seatList.get(i).classPrice.multiply(rf.rescheRate).intValue()) + "元") + ";";
                                        }
                                        cabinInfo.CabinRule.Change = rescheRules.trim();
                                    }
                                    if (seatList.get(i).luggageRegList.stream().count() > 0) {
                                        String luggage1 = "";
                                        String luggage2 = "";
                                        //改期规定
                                        for (LuggageReg rf : seatList.get(i).luggageRegList) {
                                            if (rf.luggageRegType.equals("0")) {
                                                luggage1 = "手提行李:" + rf.luggageRegPiece + "件长宽高不超过" + rf.luggageRegVolume + ",重量" + rf.luggageRegWeight + "kg。";
                                            }
                                            if (rf.luggageRegType.equals("1")) {
                                                luggage2 = "托运行李:长宽高不超过" + rf.luggageRegVolume + ",重量" + rf.luggageRegWeight + "kg";
                                            }
                                        }
                                        cabinInfo.CabinRule.Baggage = luggage1 + luggage2;
                                    }
                                    //儿童价格解析放到最后
                                    int chdNum = i++;
                                    cabinInfo.CallCenterAmountInfo.ChdTicketAmount = seatList.get(chdNum).classPrice;
                                    //儿童票价减佣金后的价格
                                    cabinInfo.CallCenterAmountInfo.OrgChdTicketAmount = seatList.get(chdNum).agencyFee.intValue() <= 0 ? seatList.get(chdNum).classPrice : seatList.get(chdNum).classPrice.subtract(seatList.get(chdNum).agencyFee);
                                    //有价格才添加航班信息
                                    if (seatList.get(i).classPrice.intValue() > 0) {
                                        flightInfo.ListCabinInfo.add(cabinInfo);
                                    }
                                }
                            }
                        }*/
                        //添加航班节点
                        response.ListGoFlightInfo.add(flightInfo);
                    }
                }
            }
            for (MoFlightInfo item : response.ListGoFlightInfo) {
                MoCabinInfo moCabinInfo;
                for (int i = 0; i < item.ListCabinInfo.size() - 1; i++) {
                    for (int j = 0; j < item.ListCabinInfo.size() - i - 1; j++) {
                        if (item.ListCabinInfo.get(j + 1).CallCenterAmountInfo.OrgTicketAmount.compareTo(item.ListCabinInfo.get(j).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                            moCabinInfo = item.ListCabinInfo.get(j);
                            item.ListCabinInfo.set(j, item.ListCabinInfo.get(j + 1));
                            item.ListCabinInfo.set(j + 1, moCabinInfo);
                        }
                    }
                }
            }
            MoFlightInfo MoFlightInfo;
            for (int i = 0; i < response.ListGoFlightInfo.size() - 1; i++) {
                for (int j = 0; j < response.ListGoFlightInfo.size() - i - 1; j++) {
                    if (response.ListGoFlightInfo.get(j + 1).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount.compareTo(response.ListGoFlightInfo.get(j).ListCabinInfo.get(0).CallCenterAmountInfo.OrgTicketAmount) == -1) {
                        MoFlightInfo = response.ListGoFlightInfo.get(j);
                        response.ListGoFlightInfo.set(j, response.ListGoFlightInfo.get(j + 1));
                        response.ListGoFlightInfo.set(j + 1, MoFlightInfo);
                    }
                }
            }
            response.IsSuccess = true;
        } catch (Exception ex) {
            ex.printStackTrace();
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {
            if (RequestCount > 0) {
                RequestCount--;
            }
        }
        return response;
    }

    /**
     * 航班预定
     * TODO 提示：下单之前计算好需要的价格。
     * 总价 = 票面价 - 基建费 -燃油费 - 代理费 （示例：总价1290、基建100、燃油40、代理费15）
     * 1290 -100 -40 -15 = 1135
     * 保存订单之前先校验航班价格、剩余座位数及婴儿座位数
     *
     * @param moCreateOrderRequest
     * @return
     */
    @Override
    public MoCreateOrderResponse _OrderCreate(MoCreateOrderRequest moCreateOrderRequest) {
        moCreateOrderRequest.OnlyCode = (moCreateOrderRequest.OnlyCode != null) ? moCreateOrderRequest.OnlyCode : strOnlyCode();
        MoCreateOrderResponse moCreateOrderResponse = new MoCreateOrderResponse();
        moCreateOrderResponse.RequestType = EnumHelper.RequestType.G5;
        moCreateOrderResponse.OnlyCode = moCreateOrderRequest.OnlyCode;
        Date RequestTime = Convert(new Date()), RequestTime_Submit = Convert(new Date());
        Date ReturnTime = Convert(new Date()), ReturnTime_Submit = Convert(new Date());
        String strRequestData = "", strResponseData = "";
        String requestPath = "stone/http/booking";
        try {
            //验证
            MoSegment goSegment = moCreateOrderRequest.ListGoSegment.get(0);
            MoPassenger moPassenger = moCreateOrderRequest.ListMoPassenger.get(0);
            if (moPassenger.TicketAmount.intValue() <= 0) {
                moCreateOrderResponse.ErrorMsg = "票价必须大于0";
                moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
                moCreateOrderResponse.IsSuccess = false;
                return moCreateOrderResponse;
            }
            //请求
            //int len = moCreateOrderRequest.OrderID.length();
            List<Object> bookingPassengerList = new ArrayList<>();
            Map<String, BigDecimal> adultInfo = new HashMap();
            Map<String, BigDecimal> childInfo = new HashMap();
            Map<String, BigDecimal> infantInfo = new HashMap();
            //总价
            BigDecimal orderAmount = new BigDecimal(0);
            //减去代理服务费金额
            BigDecimal payAmount = new BigDecimal(0);
            for (MoPassenger ps : moCreateOrderRequest.ListMoPassenger) {
                if (ps.PassengerType == 1 || ps.PassengerType == 2) {
                    ps.TicketAmount = ps.TicketAmount.add(ps.AgencyFee);
                }
                String travelerCategory = "Adult";
                if (ps.PassengerType == 1) {
                    adultInfo = new HashMap();
                    adultInfo.put("TicketAmount", ps.TicketAmount);
                    adultInfo.put("AgencyFee", ps.AgencyFee);
                    adultInfo.put("AirportTax", ps.AirportTax);
                    adultInfo.put("FuelTax", ps.FuelTax);
                    BigDecimal tempAmout = ps.TicketAmount.add(ps.AirportTax.add(ps.FuelTax));
                    orderAmount = orderAmount.add(tempAmout);
                    payAmount = payAmount.add(tempAmout.subtract(ps.AgencyFee));
                } else if (ps.PassengerType == 2) {
                    travelerCategory = "Child";
                    childInfo = new HashMap();
                    childInfo.put("TicketAmount", ps.TicketAmount);
                    childInfo.put("AgencyFee", ps.AgencyFee);
                    childInfo.put("AirportTax", ps.AirportTax);
                    childInfo.put("FuelTax", ps.FuelTax);
                    BigDecimal tempAmout = ps.TicketAmount.add(ps.AirportTax.add(ps.FuelTax));
                    orderAmount = orderAmount.add(tempAmout);
                    payAmount = payAmount.add(tempAmout.subtract(ps.AgencyFee));
                } else if (ps.PassengerType == 3) {
                    travelerCategory = "Infant";
                    infantInfo = new HashMap<>();
                    infantInfo.put("TicketAmount", ps.TicketAmount);
                    infantInfo.put("AirportTax", ps.AirportTax);
                    infantInfo.put("FuelTax", ps.FuelTax);
                    BigDecimal tempAmout = ps.TicketAmount.add(ps.AirportTax.add(ps.FuelTax));
                    orderAmount = orderAmount.add(tempAmout);
                    payAmount = payAmount.add(tempAmout);
                }
                PassengerDto info = new PassengerDto();
                info.passengerPhone = ps.PassengerMobile;
                info.passengerUserName = ps.PassengerName;
                info.passengerType = travelerCategory.toUpperCase();
                info.cardNo = ps.IDNO;
                info.cardType = ps.IDType == 1 ? "NI" : ps.IDType == 4 ? "PP" : "ID";
                if (!"Adult".equals(travelerCategory) && ps.IDType != 1) {
                    Date date = Convert(new Date());
                    if (ps.Birthday != null && ps.Birthday.getTime() > date.getTime()) {
                        info.birthDay = ps.Birthday.toString();
                    } else {
                        moCreateOrderResponse.ErrorMsg = "非成人且证件类型不是身份证时生日不能为空！";
                        moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                        moCreateOrderResponse.IsSuccess = false;
                        return moCreateOrderResponse;
                    }
                }
                bookingPassengerList.add(info);
            }
            FlightDto flight = new FlightDto();
            flight.depAirportCode = goSegment.OrgAirport;
            flight.startDate = new SimpleDateFormat("yyyy-MM-dd").format(goSegment.DepDate);
            flight.startTime = new SimpleDateFormat("HH:mm").format(goSegment.DepDate);
            flight.arrAirportCode = goSegment.DstAirport;
            flight.endDate = new SimpleDateFormat("yyyy-MM-dd").format(goSegment.ArrDate);
            flight.endTime = new SimpleDateFormat("HH:mm").format(goSegment.ArrDate);
            flight.flightNo = goSegment.FlightNo;
            flight.airline = goSegment.Airline;
            flight.classCode = goSegment.Cabin;
            if (adultInfo.size() > 0) {
                for (Map.Entry<String, BigDecimal> adult : adultInfo.entrySet()) {
                    if ("TicketAmount".equals(adult.getKey())) {
                        flight.price = adult.getValue();
                    }
                    if ("AgencyFee".equals(adult.getKey())) {
                        flight.agencyFee = adult.getValue();
                    }
                    if ("AirportTax".equals(adult.getKey())) {
                        flight.airportTax = adult.getValue();
                    }
                    if ("FuelTax".equals(adult.getKey())) {
                        flight.fuelTax = adult.getValue();
                    }
                }
            }
            if (childInfo.size() > 0) {
                for (Map.Entry<String, BigDecimal> child : childInfo.entrySet()) {
                    if ("TicketAmount".equals(child.getKey())) {
                        flight.childPrice = child.getValue();
                    }
                    if ("AgencyFee".equals(child.getKey())) {
                        flight.childAgencyFee = child.getValue();
                    }
                    if ("AirportTax".equals(child.getKey())) {
                        flight.childAirportTax = child.getValue();
                    }
                    if ("FuelTax".equals(child.getKey())) {
                        flight.childFueTax = child.getValue();
                    }
                }
            }
            if (infantInfo.size() > 0) {
                for (Map.Entry<String, BigDecimal> infant : infantInfo.entrySet()) {
                    if ("TicketAmount".equals(infant.getKey())) {
                        flight.babyPrice = infant.getValue();
                    }
                    if ("AirportTax".equals(infant.getKey())) {
                        flight.babyAirportTax = infant.getValue();
                    }
                    if ("FuelTax".equals(infant.getKey())) {
                        flight.babyFueTax = infant.getValue();
                    }
                }
            }
            Map<String, Object> createRequest = new HashMap<>();
            createRequest.put("pubChannel", "jsj");
            createRequest.put("userName", BookingContactInfo.ContactName);
            createRequest.put("passengerDtoList", bookingPassengerList);
            createRequest.put("flightDto", flight);
            //createRequest.put("flightType", "1");

            Map<String, Object> contactDto = new HashMap<>();
            contactDto.put("contactName", BookingContactInfo.ContactName);
            contactDto.put("contactEmail", BookingContactInfo.Email);
            contactDto.put("contactPhone", BookingContactInfo.MobilePhone);

            createRequest.put("contactDto", contactDto);
            createRequest.put("orderAmount", orderAmount);
            createRequest.put("flightType", goSegment.ProductType);

            //航班预订
            RequestTime = new Date();
            strRequestData = JSON.toJSONString(createRequest);
            strResponseData = new _G5().send(requestPath, strRequestData);
            ReturnTime = new Date();
            if (StringUtils.isWhitespace(strResponseData)) {
                moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                moCreateOrderResponse.ErrorMsg = "创建订单,未返回数据";
                moCreateOrderResponse.IsSuccess = false;
                return moCreateOrderResponse;
            }
            //结果集反序列化
            BookingResultDto g5CreateResponse = JSON.parseObject(strResponseData, BookingResultDto.class);
            if (g5CreateResponse != null) {
                if (!"1".equals(g5CreateResponse.result)) {
                    if (g5CreateResponse.result.equals("3")) {
                        moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                        moCreateOrderResponse.ErrorMsg = "乘客为失信人！";
                        moCreateOrderResponse.IsSuccess = false;
                        return moCreateOrderResponse;
                    } else {
                        moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                        moCreateOrderResponse.ErrorMsg = g5CreateResponse.msg;
                        moCreateOrderResponse.IsSuccess = false;
                        return moCreateOrderResponse;
                    }
                }
            } else {
                moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                moCreateOrderResponse.ErrorMsg = "提交订单失败,接口出现异常返回空值";
                moCreateOrderResponse.IsSuccess = false;
                return moCreateOrderResponse;
            }
            OrderDetailsDto details = new OrderDetailsDto();
            MoOrderDetail od = new MoOrderDetail();
            od.OrderID = details.orderNo;
            long time = 30 * 60 * 1000;
            od.PayTimeLimit = new Date(ReturnTime.getTime() + time);

            moCreateOrderResponse.PayAmount = payAmount;
            moCreateOrderResponse.SerialNumber = details.orderNo;
            moCreateOrderResponse.ListMoOrderDetail.add(od);
            moCreateOrderResponse.MainOrderID = g5CreateResponse.orderNo;
            moCreateOrderResponse.IsSuccess = true;
        } catch (Exception ex) {
            moCreateOrderResponse.ErrorMsg = ex.getMessage();
            moCreateOrderResponse.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            moCreateOrderResponse.IsSuccess = false;
        }
        return moCreateOrderResponse;
    }

    /**
     * 取消订单
     *
     * @param request
     * @return
     */
    @Override
    public MoCancelOrderResponse _CancelOrder(MoCancelOrderRequest request) {
        MoCancelOrderResponse response = new MoCancelOrderResponse();
        response.RequestType = EnumHelper.RequestType.G5;
        response.OnlyCode = request.OnlyCode;
        String strRequestData = "";
        String strResponseData = "";
        Date requestTime = new Date();
        Date returnTime = new Date();
        String requestPath = "stone/http/orderCancel";
        try {
            //验证token
            if (StringUtils.isEmpty(request.ListOrderItem.OrderID)) {
                response.ErrorMsg = EnumHelper.ReturnCode.请求参数为空.toString();
                response.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
                response.IsSuccess = false;
                return response;
            }
            Map<String, Object> parms = new HashMap<>();
            parms.put("pubChannel", "jsj");
            parms.put("orderNo", request.ListOrderItem.OrderID);
            strRequestData = JSON.toJSONString(parms);
            strResponseData = new _G5().send(requestPath, strRequestData);
            returnTime = new Date();
            if (StringUtils.isWhitespace(strResponseData)) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "取消失败，未返回数据";
                response.IsSuccess = false;
                return response;
            }
            // 判断是否是基类错误
            ReturnOrderDto baseResponse = JSON.parseObject(strResponseData, ReturnOrderDto.class);
            if (!"1".equals(baseResponse.result)) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = baseResponse.msg;
                response.IsSuccess = false;
                return response;
            } else {
                response.ErrorCode = EnumHelper.ReturnCode.成功.toString();
                response.ErrorMsg = baseResponse.msg;
                response.IsSuccess = true;
            }
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
        return response;
    }

    /**
     * 订单支付出票
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoOrderPayResponse _OrderPay(MoOrderPayRequest moRequest) {
        moRequest.OnlyCode = moRequest.OnlyCode != null ? moRequest.OnlyCode : strOnlyCode();
        MoOrderPayResponse response = new MoOrderPayResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        String requestPath = "stone/http/send/sendOrder";
        Date requestTime = new Date();
        Date returnTime = new Date();
        try {
            //验证
//            if (StringUtils.isEmpty(moRequest.MainOutOrderID)) {
//                response.ErrorMsg = "主订单号-不能为空";
//                response.IsSuccess = false;
//                return response;
//            }
//            if (StringUtils.isEmpty(moRequest.PayId)) {
//                response.ErrorMsg = "支付流水号-不能为空";
//                response.IsSuccess = false;
//                return response;
//            }
//            if (StringUtils.isEmpty(moRequest.OrderID)) {
//                response.ErrorMsg = "订单号-不能为空";
//                response.IsSuccess = false;
//                return response;
//            }
            Map<String, Object> parms = new HashMap<>();
            parms.put("pubChannel", "jsj");
            parms.put("orderNo", moRequest.OrderID);
            parms.put("payNo", moRequest.PayId);//易宝支付商户订单号传的OrderID，所以华夏出票以OrderID为支付交易号
            strRequestData = JSON.toJSONString(parms);
            strResponseData = new _G5().send(requestPath, strRequestData);
            returnTime = new Date();
            if (StringUtils.isWhitespace(strResponseData)) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "支付失败，未返回数据";
                response.IsSuccess = false;
                return response;
            }
            // 验价实体处理
            SendOrderDto g5Response = JSON.parseObject(strResponseData, SendOrderDto.class);
            if ("1".equals(g5Response.result)) {
                // 数据处理
                response.PayInfo.TradeId = moRequest.PayId;
                response.IsSuccess = true;
                response.banksDtoList = g5Response.banksDtoList;
                return response;
            } else {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = g5Response.msg;
                response.IsSuccess = false;
                return response;
            }
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
    }

    /**
     * 订单基本信息查询
     *
     * @param request
     * @return
     */
    @Override
    public MoQueryOrderResponse _QueryOrderInfo(MoQueryOrderRequest request) {
        //用于区分明细查询还是快速查询
        if (request.QueryTicketNoOnly) {
            //return _QueryFastOrderInfo(request);
        }
        MoQueryOrderResponse response = new MoQueryOrderResponse();
        response.RequestType = EnumHelper.RequestType.G5;
        response.OnlyCode = request.OnlyCode;
        String strRequestData = "";
        String strResponseData = "";
        Date requestTime = new Date();
        Date returnTime = new Date();
        String requestPath = "stone/http/orderDetails/query";
        try {
            //验证
            if (StringUtils.isEmpty(request.OrderID)) {
                response.ErrorMsg = EnumHelper.ReturnCode.请求参数为空.toString();
                response.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
                return response;
            }
            Map<String, Object> parms = new HashMap<>();
            parms.put("pubChannel", "jsj");
            parms.put("orderNo", request.OrderID);
            strRequestData = JSON.toJSONString(parms);
            strResponseData = new _G5().send(requestPath, strRequestData);
            returnTime = new Date();
            if (StringUtils.isWhitespace(strResponseData)) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "订单详情查询失败，未返回数据";
                response.IsSuccess = false;
                return response;
            }
            OrderDetailsResult result = JSON.parseObject(strResponseData, OrderDetailsResult.class);
            if ("OK".equals(result.status)) {
                OrderDetailsDto drResponse = result.content;
                if (drResponse.msg.equals("订单不存在")) {
                    response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                    response.ErrorMsg = drResponse.msg;
                    response.IsSuccess = false;
                    return response;
                }
                //订单信息
                response.OrderID = drResponse.orderNo;
                //response.OrderStatus = ChinaExpressEnum.OrderStatus.valueOf(GetPayStateConvert(drResponse.orderState)).ordinal();
                //支付信息
                for (PayInfoDto item : drResponse.payInfoDtoList) {
                    //订单金额
                    response.Amount = item.dealPrice;
                    MoPayInfo moPayInfo = new MoPayInfo();
                    if (moPayInfo.PayStatus == ChinaExpressEnum.OrderStatus.OrderStatus201.ordinal()) {
                        moPayInfo.PayAmount = item.dealPrice;
                        //实际支付金额
                        response.PayAmount = item.dealPrice;
                    }
                    //支付商户订单号用于支付的回传
                    moPayInfo.SwiftNumber = item.deal;
                    response.ListPayInfo.add(moPayInfo);
                }
                //乘机人信息
                for (PassengerListDto pl : drResponse.passengerListDtoList) {
                    //pnr唯一标识
                    response.Pnr = pl.pnrCode;
                    //乘机人信息
                    MoPassenger mopassenger = new MoPassenger();
                    //乘机人名
                    mopassenger.PNR = pl.pnrCode;
                    mopassenger.PassengerName = pl.passengerUsername;
                    mopassenger.IDNO = pl.cardNo;
                    mopassenger.TicketAmount = pl.price;
                    mopassenger.AirportTax = pl.airportTax;
                    mopassenger.FuelTax = pl.fuelsurTax;
                    //TODO mopassenger.Status = ChinaExpressEnum.OrderStatus.valueOf(GetPayStateConvert(pl.voyageStaCode)).ordinal();
                    //票号信息
                    String ticketNo = pl.ticketCode;
                    if (!StringUtils.isNotEmpty(ticketNo) && ticketNo != null) {
                        String passengerTicketStatus = pl.ticketStatus;
                        if (!ticketNo.contains("-")) {
                            ticketNo = ticketNo.replace("3", "-");
                        }
                        if (passengerTicketStatus == "C") {
                            TicketNoInfo tn = new TicketNoInfo();
                            tn.TicketNo = ticketNo;
                            mopassenger.ListTicketNoInfo.add(tn);
                        } else {
                            mopassenger.TicketNo = ticketNo;
                        }
                    }
                    //判断出票状态
                    if (!StringUtils.isNotEmpty(mopassenger.TicketNo)) {
                        mopassenger.Status = ChinaExpressEnum.OrderStatus.OrderStatus301.ordinal();
                    }
                    response.ListMoPassenger.add(mopassenger);
                }
                //航段信息
                for (FlightOneWayDto lel : drResponse.flightOneWayDtoList) {
                    MoSegment seg = new MoSegment();
                    //seg.SegID = lel.ID;
                    seg.FlightNo = lel.flightNo;
                    seg.Cabin = lel.code;
                    seg.OrgAirport = lel.boardPoint;
                    seg.DstAirport = lel.offPoint;
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    seg.DepDate = dateFormat.parse(lel.departureDate + " " + lel.departureTime);
                    seg.ArrDate = dateFormat.parse(lel.arriveDate + " " + lel.arrivalTime);
                    response.ListGoSegment.add(seg);
                }
                response.IsSuccess = true;
            } else {
                // 错误的
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = result.msg;
                response.IsSuccess = false;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
        return response;
    }

    /**
     * 退票申请确认接口
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoOrderRefundResponse _OrderRefund(MoOrderRefundRequest moRequest) {
        moRequest.OnlyCode = moRequest.OnlyCode != null ? moRequest.OnlyCode : strOnlyCode();
        MoOrderRefundResponse response = new MoOrderRefundResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        String requestPath = "stone/http/refund/refundTicket";
        Date requestTime = new Date();
        Date returnTime = new Date();
        //验证
        if (moRequest.RefundType != EnumHelper.RefundType.自愿.getValue()) {
            response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
            response.ErrorMsg = moRequest.RefundType + "非自愿情况只能通过线下客服提交退票";
            return response;
        }
        if (StringUtils.isEmpty(moRequest.OrderID)) {
            response.ErrorMsg = "订单号不能为空";
            response.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
            return response;
        }
        try {
            String refundType = "";
            String reason = "";
            if (moRequest.RefundType == EnumHelper.RefundType.自愿.getValue()) {
                refundType = "A";
                if (moRequest.RefundCause == EnumHelper.RefundCause.手误选错日期.getValue() || moRequest.RefundCause == EnumHelper.RefundCause.手误选错航班.getValue() || moRequest.RefundCause == EnumHelper.RefundCause.手误乘机人或联系人填写错误.getValue()) {
                    reason = "A";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.行程计划改变.getValue()) {
                    reason = "B";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.我不想飞了.getValue()) {
                    reason = "C";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.重复购买了相同的航班.getValue()) {
                    reason = "D";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.在其他地方发现了更便宜的价格.getValue()) {
                    reason = "E";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.其他.getValue()) {
                    reason = "F";
                }
            } else if (moRequest.RefundType == EnumHelper.RefundType.其他非自愿.getValue()) {
                refundType = "B";
                if (moRequest.RefundCause == EnumHelper.RefundCause.身体不适无法飞行.getValue()) {
                    reason = "A";
                    if (moRequest.ListAttachment.stream().count() <= 0) {
                        response.ErrorMsg = "请上传病退证明";
                        return response;
                    }
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.航班延误.getValue()) {
                    reason = "B";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.航班取消.getValue()) {
                    reason = "C";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.重复购买了相同的航班.getValue()) {
                    reason = "D";
                } else if (moRequest.RefundCause == EnumHelper.RefundCause.其他.getValue()) {
                    reason = "E";
                }
            }

            String ticketNoStr = "";
            for (MoPassenger item : moRequest.ListMoPassenger) {
                ticketNoStr += item.TicketNo + ",";
            }
            /*if (moRequest.RefundType == EnumHelper.RefundType.自愿.getValue()) {
                reason = "C";
            } else {
                if (moRequest.RefundType == EnumHelper.RefundType.病退.getValue()) {
                    if (moRequest.ListAttachment.stream().count() <= 0) {
                        response.ErrorMsg = "请上传病退证明";
                        return response;
                    }
                    reason = "A";
                } else if (moRequest.RefundType == EnumHelper.RefundType.航变.getValue()) {
                    reason = "B";
                } else if (moRequest.RefundType == EnumHelper.RefundType.航班取消.getValue()) {
                    reason = "C";
                } else if (moRequest.RefundType == EnumHelper.RefundType.重购全退.getValue()) {
                    reason = "D";
                } else {
                    reason = "E";
                }
            }*/
            Map<String, Object> parms = new HashMap<>();
            parms.put("orderNo", moRequest.OrderID);
            parms.put("ticketNoStr", ticketNoStr.trim());
            //parms.put("refundReason", moRequest.RefundType == EnumHelper.RefundType.自愿.getValue() ? "A" : "B");
            parms.put("refundReason", refundType);
            parms.put("refundReasonInfo", reason);
            parms.put("pubChannel", "jsj");
            strRequestData = JSON.toJSONString(parms);
            strResponseData = new _G5().send(requestPath, strRequestData);
            returnTime = new Date();
            if (StringUtils.isWhitespace(strResponseData)) {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "申请退票，未返回数据";
                response.IsSuccess = false;
                return response;
            }
            RefundTicketDto g5Response = JSON.parseObject(strResponseData, RefundTicketDto.class);
            if (!"1".equals(g5Response.result)) {
                // 错误的
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = g5Response.msg;
                response.IsSuccess = false;
                return response;
            }
            response.RefundOrderID = g5Response.refundNo;
            response.ErrorMsg = g5Response.msg;
            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage();
            return response;
        } finally {

        }
        return response;
    }

    /**
     * 查询退票手续费
     *
     * @param request
     * @param isSubsidy
     * @return
     */
    @Override
    public MoOrderRefundCaltResponse _OrderRefundCalt(MoOrderRefundCaltRequest request, boolean isSubsidy) {
        isSubsidy = true;
        MoOrderRefundCaltResponse response = new MoOrderRefundCaltResponse();
        String strRequestData = "";
        String strResponseData = "";
        String requestPath = "stone/http/refund/queryRefundFee";
        Date requestTime = new Date();
        Date returnTime = new Date();
        try {
            //参数验证
            if (!StringUtils.isNotEmpty(request.OutOrderID)) {
                response.ErrorMsg = "订单号不能为空";
                response.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
                return response;
            }
            if (request.ListMoPassenger == null || request.ListMoPassenger.stream().count() <= 0) {
                response.ErrorMsg = "乘机人票号信息不能为空";
                response.ErrorCode = EnumHelper.ReturnCode.请求参数为空.toString();
                return response;
            }
            MoPassenger moPassenger = request.ListMoPassenger.get(0);
            String refundType = "";
            if (request.RefundType == EnumHelper.RefundType.自愿.getValue()) {
                refundType = "A";
            } else if (request.RefundType == EnumHelper.RefundType.其他非自愿.getValue()) {
                refundType = "B";
            }
            //构造请求参数
            Map<String, Object> parms = new HashMap<>();
            parms.put("ticketNo", moPassenger.TicketNo);
            parms.put("orderNo", request.OutOrderID);
            //parms.put("refundType", request.RefundType == EnumHelper.RefundType.病退.getValue() ? "A" : "B");
            parms.put("refundType", refundType);
            parms.put("pubChannel", "jsj");
            //发起请求
            strRequestData = JSON.toJSONString(parms);
            requestTime = new Date();
            strResponseData = new _G5().send(requestPath, strRequestData);
            returnTime = new Date();
            //将请求结果转化成实体类
            RefundFeeDto rsp = JSON.parseObject(strResponseData, RefundFeeDto.class);
            //解析返回信息
            if (!"1".equals(rsp.getResult())) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = rsp.getMsg();
                return response;
            }
            //解析需要的数据
            for (MoPassenger item : request.ListMoPassenger) {
                MoPassenger p = new MoPassenger();
                p.TicketNo = item.TicketNo;
                p.IDNO = item.IDNO;
                p.PassengerName = item.PassengerName;
                p.TicketAmount = item.TicketAmount;
                p.AirportTax = rsp.getRefundAirportTax();
                p.FuelTax = rsp.getRefundFuelTax();
                p.RefundFee = rsp.getRefundPoundage();
                response.ListRefundPassenger.add(p);
                break;
            }
            response.Amount = rsp.getRefundMoney();
            response.IsSuccess = true;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
        return response;
    }

    /**
     * 获取航线退改签规则
     *
     * @param moRequest
     * @return
     */
    @Override
    public MoCabinTgqResponse _GetCabinTgq(MoCabinTgqRequest moRequest) {
        moRequest.OnlyCode = moRequest.OnlyCode != null ? moRequest.OnlyCode : strOnlyCode();
        MoCabinTgqResponse response = new MoCabinTgqResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        Date requestTime = new Date();
        Date returnTime = new Date();
        try {
            requestTime = new Date();
            strResponseData = "";
            returnTime = new Date();
            response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
            response.ErrorMsg = "不支持改签";
            response.IsSuccess = false;
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
        return response;
    }

    private String send(String path, String content) {
        try {
            EncryptMessageModel model = new EncryptMessageModel(userName, password, content);
            RSAPublicKey publicKey = RSAUtil.string2PublicKey(rsaKey);
            String postStr = EncryptHelper.encrypt(model, publicKey, aesPassWord);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            MultiValueMap<String, String> values = new LinkedMultiValueMap<>();
            values.add("content", postStr);
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(values, headers);
            long start = System.currentTimeMillis();
            ResponseEntity<String> response = restTemplate.postForEntity((url + path), request, String.class);
            long end = System.currentTimeMillis();
            long sub = (end - start);
            if (response != null) {
                String responseString = response.getBody();
                if (StringUtils.isNotEmpty(responseString)) {
                    String resultCode = ZipUtils.gunzip(responseString);
                    if (StringUtils.isNotEmpty(resultCode)) {
                        JSONObject obj = JSON.parseObject(resultCode);
                        String objContent = obj.getString("content");
                        String status = obj.getString("code");
                        if ("OK".equals(status)) {
                            if (StringUtils.isNotEmpty(objContent)) {
                                String decr = AesUtil.decrypt(objContent, aesPassWord);
                                return decr;
                            }
                        } else {
                            System.out.println("status is not ok");
                        }
                    }
                }
            }
        } catch (Exception e) {
            String errMessage = String.format("发起http请求出现异常:{0}", e.getMessage());
            return errMessage;
        }
        return "NO";
    }

    private Date Convert(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime start = localDateTime.with(LocalTime.MIN);
        return Date.from(start.atZone(ZoneId.systemDefault()).toInstant());
    }

    private String data(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }

    private String strOnlyCode() {
        return data(new Date()) + new Random().ints(1000, 10000);
    }

    /**
     * 支付状态转换
     *
     * @param strDr
     * @return
     */
    private String GetPayStateConvert(String strDr) {
        switch (strDr) {
            case "A":
                return "支付成功";
            case "B":
            case "O":
                return "等待支付";
            case "C":
                return "行程单已出";
            case "D":
                return "出票完成";
            case "F":
                return "等待出票";
            case "G":
            case "R":
                return "订单取消";
            case "1":
                return "支付成功";
            case "0":
                return "支付失败";

            default:
                return strDr;
        }
    }

    public static Date convertToDate(String str, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Date date = null;
        if (str != null) {
            try {
                date = format.parse(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return date;
    }

    /**
     * 根据机场三字码获取机场名称
     *
     * @return
     */
    private String getAirPortNameByRirPortCode(String airPortCode) {
        if (airportService == null) {
            return airPortCode;
        }
        Airport airport = airportService.getAirPortNameByRirPortCode(airPortCode);
        return airport.getAirnamesort();
    }
}
